home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / ftp / RCS / main.c,v < prev    next >
Encoding:
Text File  |  1991-08-20  |  11.3 KB  |  657 lines

  1. head     1.4;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.4
  10. date     91.08.20.10.24.55;  author mendel;  state Exp;
  11. branches ;
  12. next     1.3;
  13.  
  14. 1.3
  15. date     90.10.27.13.48.44;  author shirriff;  state Exp;
  16. branches ;
  17. next     1.2;
  18.  
  19. 1.2
  20. date     90.04.17.14.02.40;  author mendel;  state Exp;
  21. branches ;
  22. next     1.1;
  23.  
  24. 1.1
  25. date     90.04.17.13.53.16;  author mendel;  state Exp;
  26. branches ;
  27. next     ;
  28.  
  29.  
  30. desc
  31. @@
  32.  
  33.  
  34. 1.4
  35. log
  36. @Merged back in the changes from 1.1 to 1.2 into 1.3.
  37. @
  38. text
  39. @/*
  40.  * Copyright (c) 1985, 1989 Regents of the University of California.
  41.  * All rights reserved.
  42.  *
  43.  * Redistribution and use in source and binary forms are permitted
  44.  * provided that the above copyright notice and this paragraph are
  45.  * duplicated in all such forms and that any documentation,
  46.  * advertising materials, and other materials related to such
  47.  * distribution and use acknowledge that the software was developed
  48.  * by the University of California, Berkeley.  The name of the
  49.  * University may not be used to endorse or promote products derived
  50.  * from this software without specific prior written permission.
  51.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  52.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  53.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  54.  */
  55.  
  56. #ifndef lint
  57. char copyright[] =
  58. "@@(#) Copyright (c) 1985, 1989 Regents of the University of California.\n\
  59.  All rights reserved.\n";
  60. #endif /* not lint */
  61.  
  62. #ifndef lint
  63. static char sccsid[] = "@@(#)main.c    5.13 (Berkeley) 3/14/89";
  64. #endif /* not lint */
  65.  
  66. /*
  67.  * FTP User Program -- Command Interface.
  68.  */
  69. #include "ftp_var.h"
  70. #include <sys/socket.h>
  71. #include <sys/ioctl.h>
  72. #include <sys/types.h>
  73.  
  74. #include <arpa/ftp.h>
  75.  
  76. #include <signal.h>
  77. #include <stdio.h>
  78. #include <errno.h>
  79. #include <ctype.h>
  80. #include <netdb.h>
  81. #include <pwd.h>
  82.  
  83.  
  84. uid_t    getuid();
  85. int    intr();
  86. int    lostpeer();
  87. extern    char *home;
  88. char    *getlogin();
  89.  
  90. main(argc, argv)
  91.     char *argv[];
  92. {
  93.     register char *cp;
  94.     int top;
  95.     struct passwd *pw = NULL;
  96.     char homedir[MAXPATHLEN];
  97.  
  98.     sp = getservbyname("ftp", "tcp");
  99.     if (sp == 0) {
  100.         fprintf(stderr, "ftp: ftp/tcp: unknown service\n");
  101.         exit(1);
  102.     }
  103.     doglob = 1;
  104.     interactive = 1;
  105.     autologin = 1;
  106.     argc--, argv++;
  107.     while (argc > 0 && **argv == '-') {
  108.         for (cp = *argv + 1; *cp; cp++)
  109.             switch (*cp) {
  110.  
  111.             case 'd':
  112.                 options |= SO_DEBUG;
  113.                 debug++;
  114.                 break;
  115.             
  116.             case 'v':
  117.                 verbose++;
  118.                 break;
  119.  
  120.             case 't':
  121.                 trace++;
  122.                 break;
  123.  
  124.             case 'i':
  125.                 interactive = 0;
  126.                 break;
  127.  
  128.             case 'n':
  129.                 autologin = 0;
  130.                 break;
  131.  
  132.             case 'g':
  133.                 doglob = 0;
  134.                 break;
  135.  
  136.             default:
  137.                 fprintf(stdout,
  138.                   "ftp: %c: unknown option\n", *cp);
  139.                 exit(1);
  140.             }
  141.         argc--, argv++;
  142.     }
  143.     fromatty = isatty(fileno(stdin));
  144.     /*
  145.      * Set up defaults for FTP.
  146.      */
  147.     (void) strcpy(typename, "ascii"), type = TYPE_A;
  148.     (void) strcpy(formname, "non-print"), form = FORM_N;
  149.     (void) strcpy(modename, "stream"), mode = MODE_S;
  150.     (void) strcpy(structname, "file"), stru = STRU_F;
  151.     (void) strcpy(bytename, "8"), bytesize = 8;
  152.     if (fromatty)
  153.         verbose++;
  154.     cpend = 0;           /* no pending replies */
  155.     proxy = 0;    /* proxy not active */
  156.     crflag = 1;    /* strip c.r. on ascii gets */
  157.     /*
  158.      * Set up the home directory in case we're globbing.
  159.      */
  160.     cp = getlogin();
  161.     if (cp != NULL) {
  162.         pw = getpwnam(cp);
  163.     }
  164.     if (pw == NULL)
  165.         pw = getpwuid(getuid());
  166.     if (pw != NULL) {
  167.         home = homedir;
  168.         (void) strcpy(home, pw->pw_dir);
  169.     }
  170.     if (argc > 0) {
  171.         if (setjmp(toplevel))
  172.             exit(0);
  173.         (void) signal(SIGINT, intr);
  174.         (void) signal(SIGPIPE, lostpeer);
  175.         setpeer(argc + 1, argv - 1);
  176.     }
  177.     top = setjmp(toplevel) == 0;
  178.     if (top) {
  179.         (void) signal(SIGINT, intr);
  180.         (void) signal(SIGPIPE, lostpeer);
  181.     }
  182.     for (;;) {
  183.         cmdscanner(top);
  184.         top = 1;
  185.     }
  186. }
  187.  
  188. intr()
  189. {
  190.  
  191.     longjmp(toplevel, 1);
  192. }
  193.  
  194. lostpeer()
  195. {
  196.     extern FILE *cout;
  197.     extern int data;
  198.  
  199.     if (connected) {
  200.         if (cout != NULL) {
  201.             (void) shutdown(fileno(cout), 1+1);
  202.             (void) fclose(cout);
  203.             cout = NULL;
  204.         }
  205.         if (data >= 0) {
  206.             (void) shutdown(data, 1+1);
  207.             (void) close(data);
  208.             data = -1;
  209.         }
  210.         connected = 0;
  211.     }
  212.     pswitch(1);
  213.     if (connected) {
  214.         if (cout != NULL) {
  215.             (void) shutdown(fileno(cout), 1+1);
  216.             (void) fclose(cout);
  217.             cout = NULL;
  218.         }
  219.         connected = 0;
  220.     }
  221.     proxflag = 0;
  222.     pswitch(0);
  223. }
  224.  
  225. /*char *
  226. tail(filename)
  227.     char *filename;
  228. {
  229.     register char *s;
  230.     
  231.     while (*filename) {
  232.         s = rindex(filename, '/');
  233.         if (s == NULL)
  234.             break;
  235.         if (s[1])
  236.             return (s + 1);
  237.         *s = '\0';
  238.     }
  239.     return (filename);
  240. }
  241. */
  242. /*
  243.  * Command parser.
  244.  */
  245. cmdscanner(top)
  246.     int top;
  247. {
  248.     register struct cmd *c;
  249.     struct cmd *getcmd();
  250.     extern int help();
  251.  
  252.     if (!top)
  253.         (void) putchar('\n');
  254.     for (;;) {
  255.         if (fromatty) {
  256.             printf("ftp> ");
  257.             (void) fflush(stdout);
  258.         }
  259.         if (gets(line) == 0) {
  260.             if (feof(stdin) || ferror(stdin))
  261.                 quit();
  262.             break;
  263.         }
  264.         if (line[0] == 0)
  265.             break;
  266.         makeargv();
  267.         if (margc == 0) {
  268.             continue;
  269.         }
  270.         c = getcmd(margv[0]);
  271.         if (c == (struct cmd *)-1) {
  272.             printf("?Ambiguous command\n");
  273.             continue;
  274.         }
  275.         if (c == 0) {
  276.             printf("?Invalid command\n");
  277.             continue;
  278.         }
  279.         if (c->c_conn && !connected) {
  280.             printf ("Not connected.\n");
  281.             continue;
  282.         }
  283.         (*c->c_handler)(margc, margv);
  284.         if (bell && c->c_bell)
  285.             (void) putchar('\007');
  286.         if (c->c_handler != help)
  287.             break;
  288.     }
  289.     (void) signal(SIGINT, intr);
  290.     (void) signal(SIGPIPE, lostpeer);
  291. }
  292.  
  293. struct cmd *
  294. getcmd(name)
  295.     register char *name;
  296. {
  297.     extern struct cmd cmdtab[];
  298.     register char *p, *q;
  299.     register struct cmd *c, *found;
  300.     register int nmatches, longest;
  301.  
  302.     longest = 0;
  303.     nmatches = 0;
  304.     found = 0;
  305.     for (c = cmdtab; p = c->c_name; c++) {
  306.         for (q = name; *q == *p++; q++)
  307.             if (*q == 0)        /* exact match? */
  308.                 return (c);
  309.         if (!*q) {            /* the name was a prefix */
  310.             if (q - name > longest) {
  311.                 longest = q - name;
  312.                 nmatches = 1;
  313.                 found = c;
  314.             } else if (q - name == longest)
  315.                 nmatches++;
  316.         }
  317.     }
  318.     if (nmatches > 1)
  319.         return ((struct cmd *)-1);
  320.     return (found);
  321. }
  322.  
  323. /*
  324.  * Slice a string up into argc/argv.
  325.  */
  326.  
  327. int slrflag;
  328.  
  329. makeargv()
  330. {
  331.     char **argp;
  332.     char *slurpstring();
  333.  
  334.     margc = 0;
  335.     argp = margv;
  336.     stringbase = line;        /* scan from first of buffer */
  337.     argbase = argbuf;        /* store from first of buffer */
  338.     slrflag = 0;
  339.     while (*argp++ = slurpstring())
  340.         margc++;
  341. }
  342.  
  343. /*
  344.  * Parse string into argbuf;
  345.  * implemented with FSM to
  346.  * handle quoting and strings
  347.  */
  348. char *
  349. slurpstring()
  350. {
  351.     int got_one = 0;
  352.     register char *sb = stringbase;
  353.     register char *ap = argbase;
  354.     char *tmp = argbase;        /* will return this if token found */
  355.  
  356.     if (*sb == '!' || *sb == '$') {    /* recognize ! as a token for shell */
  357.         switch (slrflag) {    /* and $ as token for macro invoke */
  358.             case 0:
  359.                 slrflag++;
  360.                 stringbase++;
  361.                 return ((*sb == '!') ? "!" : "$");
  362.                 /* NOTREACHED */
  363.             case 1:
  364.                 slrflag++;
  365.                 altarg = stringbase;
  366.                 break;
  367.             default:
  368.                 break;
  369.         }
  370.     }
  371.  
  372. S0:
  373.     switch (*sb) {
  374.  
  375.     case '\0':
  376.         goto OUT;
  377.  
  378.     case ' ':
  379.     case '\t':
  380.         sb++; goto S0;
  381.  
  382.     default:
  383.         switch (slrflag) {
  384.             case 0:
  385.                 slrflag++;
  386.                 break;
  387.             case 1:
  388.                 slrflag++;
  389.                 altarg = sb;
  390.                 break;
  391.             default:
  392.                 break;
  393.         }
  394.         goto S1;
  395.     }
  396.  
  397. S1:
  398.     switch (*sb) {
  399.  
  400.     case ' ':
  401.     case '\t':
  402.     case '\0':
  403.         goto OUT;    /* end of token */
  404.  
  405.     case '\\':
  406.         sb++; goto S2;    /* slurp next character */
  407.  
  408.     case '"':
  409.         sb++; goto S3;    /* slurp quoted string */
  410.  
  411.     default:
  412.         *ap++ = *sb++;    /* add character to token */
  413.         got_one = 1;
  414.         goto S1;
  415.     }
  416.  
  417. S2:
  418.     switch (*sb) {
  419.  
  420.     case '\0':
  421.         goto OUT;
  422.  
  423.     default:
  424.         *ap++ = *sb++;
  425.         got_one = 1;
  426.         goto S1;
  427.     }
  428.  
  429. S3:
  430.     switch (*sb) {
  431.  
  432.     case '\0':
  433.         goto OUT;
  434.  
  435.     case '"':
  436.         sb++; goto S1;
  437.  
  438.     default:
  439.         *ap++ = *sb++;
  440.         got_one = 1;
  441.         goto S3;
  442.     }
  443.  
  444. OUT:
  445.     if (got_one)
  446.         *ap++ = '\0';
  447.     argbase = ap;            /* update storage pointer */
  448.     stringbase = sb;        /* update scan pointer */
  449.     if (got_one) {
  450.         return(tmp);
  451.     }
  452.     switch (slrflag) {
  453.         case 0:
  454.             slrflag++;
  455.             break;
  456.         case 1:
  457.             slrflag++;
  458.             altarg = (char *) 0;
  459.             break;
  460.         default:
  461.             break;
  462.     }
  463.     return((char *)0);
  464. }
  465.  
  466. #define HELPINDENT (sizeof ("directory"))
  467.  
  468. /*
  469.  * Help command.
  470.  * Call each command handler with argc == 0 and argv[0] == name.
  471.  */
  472. help(argc, argv)
  473.     int argc;
  474.     char *argv[];
  475. {
  476.     extern struct cmd cmdtab[];
  477.     register struct cmd *c;
  478.  
  479.     if (argc == 1) {
  480.         register int i, j, w, k;
  481.         int columns, width = 0, lines;
  482.         extern int NCMDS;
  483.  
  484.         printf("Commands may be abbreviated.  Commands are:\n\n");
  485.         for (c = cmdtab; c < &cmdtab[NCMDS]; c++) {
  486.             int len = strlen(c->c_name);
  487.  
  488.             if (len > width)
  489.                 width = len;
  490.         }
  491.         width = (width + 8) &~ 7;
  492.         columns = 80 / width;
  493.         if (columns == 0)
  494.             columns = 1;
  495.         lines = (NCMDS + columns - 1) / columns;
  496.         for (i = 0; i < lines; i++) {
  497.             for (j = 0; j < columns; j++) {
  498.                 c = cmdtab + j * lines + i;
  499.                 if (c->c_name && (!proxy || c->c_proxy)) {
  500.                     printf("%s", c->c_name);
  501.                 }
  502.                 else if (c->c_name) {
  503.                     for (k=0; k < strlen(c->c_name); k++) {
  504.                         (void) putchar(' ');
  505.                     }
  506.                 }
  507.                 if (c + lines >= &cmdtab[NCMDS]) {
  508.                     printf("\n");
  509.                     break;
  510.                 }
  511.                 w = strlen(c->c_name);
  512.                 while (w < width) {
  513.                     w = (w + 8) &~ 7;
  514.                     (void) putchar('\t');
  515.                 }
  516.             }
  517.         }
  518.         return;
  519.     }
  520.     while (--argc > 0) {
  521.         register char *arg;
  522.         arg = *++argv;
  523.         c = getcmd(arg);
  524.         if (c == (struct cmd *)-1)
  525.             printf("?Ambiguous help command %s\n", arg);
  526.         else if (c == (struct cmd *)0)
  527.             printf("?Invalid help command %s\n", arg);
  528.         else
  529.             printf("%-*s\t%s\n", HELPINDENT,
  530.                 c->c_name, c->c_help);
  531.     }
  532. }
  533.  
  534. #ifdef orig
  535. /*
  536.  * Call routine with argc, argv set from args (terminated by 0).
  537.  */
  538. /*VARARGS1*/
  539. call(routine, args)
  540.     int (*routine)();
  541.     int args;
  542. {
  543.     register int *argp;
  544.     register int argc;
  545.  
  546.     for (argc = 0, argp = &args; *argp++ != 0; argc++)
  547.         ;
  548.     (*routine)(argc, &args);
  549. }
  550. #else
  551. #include <varargs.h>
  552. /*
  553.  * Call routine with argc, argv set from args (terminated by 0).
  554.  */
  555. /*VARARGS1*/
  556. call(va_alist)
  557. va_dcl
  558. {
  559.     int (*routine)();
  560.     register char *argp;
  561.     va_list pvar;
  562.     register int argc;
  563.     char    *args[50];
  564.  
  565.     va_start(pvar);
  566.     routine = (int (*)()) va_arg(pvar, char *);
  567.     argp = va_arg(pvar, char *);
  568.     args[0] = argp;
  569.     for (argc = 0; (argp != (char *) 0) && (argc < 49); argc++) {
  570.         args[argc+1] = argp = va_arg(pvar, char *);
  571.     }
  572.     va_end(pvar);
  573.     (*routine)(argc, args);
  574. }
  575. #endif
  576. @
  577.  
  578.  
  579. 1.3
  580. log
  581. @New revision.
  582. @
  583. text
  584. @d496 1
  585. d512 26
  586. @
  587.  
  588.  
  589. 1.2
  590. log
  591. @Patched routine "call" to use varargs so it will work on sparc and mips
  592. CPUs.
  593. @
  594. text
  595. @d2 1
  596. a2 1
  597.  * Copyright (c) 1985 Regents of the University of California.
  598. d6 10
  599. a15 5
  600.  * provided that this notice is preserved and that due credit is given
  601.  * to the University of California at Berkeley. The name of the University
  602.  * may not be used to endorse or promote products derived from this
  603.  * software without specific prior written permission. This software
  604.  * is provided ``as is'' without express or implied warranty.
  605. d20 1
  606. a20 1
  607. "@@(#) Copyright (c) 1985 Regents of the University of California.\n\
  608. d25 1
  609. a25 1
  610. static char sccsid[] = "@@(#)main.c    5.10 (Berkeley) 3/14/88";
  611. d247 1
  612. a247 1
  613.             (void) putchar(CTRL('g'));
  614. d324 1
  615. a324 1
  616.                 break;
  617. a495 1
  618. #ifdef orig
  619. a510 26
  620. #else
  621. #include <varargs.h>
  622. /*
  623.  * Call routine with argc, argv set from args (terminated by 0).
  624.  */
  625. /*VARARGS1*/
  626. call(va_alist)
  627. va_dcl
  628. {
  629.     int (*routine)();
  630.     register char *argp;
  631.     va_list pvar;
  632.     register int argc;
  633.     char    *args[50];
  634.  
  635.     va_start(pvar);
  636.     routine = (int (*)()) va_arg(pvar, char *);
  637.     argp = va_arg(pvar, char *);
  638.     args[0] = argp;
  639.     for (argc = 0; (argp != (char *) 0) && (argc < 49); argc++) {
  640.         args[argc+1] = argp = va_arg(pvar, char *);
  641.     }
  642.     va_end(pvar);
  643.     (*routine)(argc, args);
  644. }
  645. #endif
  646. @
  647.  
  648.  
  649. 1.1
  650. log
  651. @Initial revision
  652. @
  653. text
  654. @d491 1
  655. d507 26
  656. @
  657.